00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef FULLMATRIXMAP_HPP_
00018 #define FULLMATRIXMAP_HPP_
00019
00020
00021
00022 #include <boost/smart_ptr/shared_ptr.hpp>
00023 #include <ga.h>
00024 #include "gridpack/parallel/parallel.hpp"
00025 #include <gridpack/parallel/distributed.hpp>
00026 #include <gridpack/component/base_component.hpp>
00027 #include <gridpack/network/base_network.hpp>
00028 #include <gridpack/math/matrix.hpp>
00029 #include <gridpack/utilities/exception.hpp>
00030
00031 #define DBG_CHECK
00032
00033 namespace gridpack {
00034 namespace mapper {
00035
00036 template <class _network>
00037 class FullMatrixMap {
00038 public:
00039
00040
00041
00042
00043
00044
00045 FullMatrixMap(boost::shared_ptr<_network> network)
00046 : p_network(network)
00047 {
00048 p_i_busOffsets = NULL;
00049 p_j_busOffsets = NULL;
00050 p_i_branchOffsets = NULL;
00051 p_j_branchOffsets = NULL;
00052 #ifdef NZ_PER_ROW
00053 p_nz_per_row = NULL;
00054 #endif
00055 int iSize = 0;
00056 int jSize = 0;
00057
00058 p_timer = NULL;
00059
00060
00061 p_GAgrp = network->communicator().getGroup();
00062 p_me = GA_Pgroup_nodeid(p_GAgrp);
00063 p_nNodes = GA_Pgroup_nnodes(p_GAgrp);
00064
00065 p_nBuses = p_network->numBuses();
00066 p_nBranches = p_network->numBranches();
00067
00068 p_activeBuses = getActiveBuses();
00069
00070 setupGlobalArrays(p_activeBuses);
00071
00072 setupIndexingArrays();
00073
00074 setupOffsetArrays();
00075
00076 contributions();
00077 GA_Pgroup_sync(p_GAgrp);
00078 setBusOffsets();
00079 setBranchOffsets();
00080
00081 }
00082
00083 ~FullMatrixMap()
00084 {
00085 if (p_i_busOffsets != NULL) delete [] p_i_busOffsets;
00086 if (p_j_busOffsets != NULL) delete [] p_j_busOffsets;
00087 if (p_i_branchOffsets != NULL) delete [] p_i_branchOffsets;
00088 if (p_j_branchOffsets != NULL) delete [] p_j_branchOffsets;
00089 #ifdef NZ_PER_ROW
00090 if (p_nz_per_row != NULL) delete [] p_nz_per_row;
00091 #endif
00092 GA_Destroy(gaOffsetI);
00093 GA_Destroy(gaOffsetJ);
00094 GA_Pgroup_sync(p_GAgrp);
00095 }
00096
00097
00098
00099
00100
00101
00102 boost::shared_ptr<gridpack::math::Matrix> mapToMatrix(bool isDense = false)
00103 {
00104 gridpack::parallel::Communicator comm = p_network->communicator();
00105 int t_new, t_bus, t_branch, t_set;
00106
00107
00108
00109 if (p_timer) t_new = p_timer->createCategory("Mapper: New Matrix");
00110 if (p_timer) p_timer->start(t_new);
00111 GA_Pgroup_sync(p_GAgrp);
00112 boost::shared_ptr<gridpack::math::Matrix> Ret;
00113 if (isDense) {
00114 Ret.reset(new gridpack::math::Matrix(comm, p_rowBlockSize, p_colBlockSize,
00115 gridpack::math::Dense));
00116 } else {
00117 #ifndef NZ_PER_ROW
00118 Ret.reset(new gridpack::math::Matrix(comm, p_rowBlockSize, p_colBlockSize,
00119 p_maxcol));
00120 #else
00121 Ret.reset(new gridpack::math::Matrix(comm, p_rowBlockSize, p_colBlockSize, p_nz_per_row));
00122 #endif
00123 }
00124 if (p_timer) p_timer->stop(t_new);
00125 if (p_timer) t_bus = p_timer->createCategory("Mapper: Load Bus Data");
00126 if (p_timer) p_timer->start(t_bus);
00127 loadBusData(*Ret,false);
00128 if (p_timer) p_timer->stop(t_bus);
00129 if (p_timer) t_branch = p_timer->createCategory("Mapper: Load Branch Data");
00130 if (p_timer) p_timer->start(t_branch);
00131 loadBranchData(*Ret,false);
00132 if (p_timer) p_timer->stop(t_branch);
00133 if (p_timer) t_set = p_timer->createCategory("Mapper: Set Matrix");
00134 if (p_timer) p_timer->start(t_set);
00135 GA_Pgroup_sync(p_GAgrp);
00136 Ret->ready();
00137 if (p_timer) p_timer->stop(t_set);
00138 return Ret;
00139 }
00140
00141
00142
00143
00144
00145
00146 boost::shared_ptr<gridpack::math::RealMatrix> mapToRealMatrix(bool isDense = false)
00147 {
00148 gridpack::parallel::Communicator comm = p_network->communicator();
00149 int t_new, t_bus, t_branch, t_set;
00150
00151
00152
00153 if (p_timer) t_new = p_timer->createCategory("Mapper: New Matrix");
00154 if (p_timer) p_timer->start(t_new);
00155 GA_Pgroup_sync(p_GAgrp);
00156 boost::shared_ptr<gridpack::math::RealMatrix> Ret;
00157 if (isDense) {
00158 Ret.reset(new gridpack::math::RealMatrix(comm, p_rowBlockSize, p_colBlockSize,
00159 gridpack::math::Dense));
00160 } else {
00161 #ifndef NZ_PER_ROW
00162 Ret.reset(new gridpack::math::RealMatrix(comm, p_rowBlockSize, p_colBlockSize,
00163 p_maxcol));
00164 #else
00165 Ret.reset(new gridpack::math::RealMatrix(comm, p_rowBlockSize, p_colBlockSize, p_nz_per_row));
00166 #endif
00167 }
00168 if (p_timer) p_timer->stop(t_new);
00169 if (p_timer) t_bus = p_timer->createCategory("Mapper: Load Bus Data");
00170 if (p_timer) p_timer->start(t_bus);
00171 loadRealBusData(*Ret,false);
00172 if (p_timer) p_timer->stop(t_bus);
00173 if (p_timer) t_branch = p_timer->createCategory("Mapper: Load Branch Data");
00174 if (p_timer) p_timer->start(t_branch);
00175 loadRealBranchData(*Ret,false);
00176 if (p_timer) p_timer->stop(t_branch);
00177 if (p_timer) t_set = p_timer->createCategory("Mapper: Set Matrix");
00178 if (p_timer) p_timer->start(t_set);
00179 GA_Pgroup_sync(p_GAgrp);
00180 Ret->ready();
00181 if (p_timer) p_timer->stop(t_set);
00182 return Ret;
00183 }
00184
00185
00186
00187
00188
00189
00190
00191 gridpack::math::Matrix* intMapToMatrix(bool isDense = false)
00192 {
00193 gridpack::parallel::Communicator comm = p_network->communicator();
00194 int t_new, t_bus, t_branch, t_set;
00195 if (p_timer) t_new = p_timer->createCategory("Mapper: New Matrix");
00196 if (p_timer) p_timer->start(t_new);
00197 GA_Pgroup_sync(p_GAgrp);
00198 gridpack::math::Matrix *Ret;
00199 if (isDense) {
00200 Ret = new gridpack::math::Matrix(comm, p_rowBlockSize, p_colBlockSize,
00201 gridpack::math::Dense);
00202 } else {
00203 #ifndef NZ_PER_ROW
00204 Ret = new gridpack::math::Matrix(comm, p_rowBlockSize, p_colBlockSize,
00205 p_maxcol);
00206 #else
00207 Ret = new gridpack::math::Matrix(comm, p_rowBlockSize, p_colBlockSize, p_nz_per_row);
00208 #endif
00209 }
00210 if (p_timer) p_timer->stop(t_new);
00211 if (p_timer) t_bus = p_timer->createCategory("Mapper: Load Bus Data");
00212 if (p_timer) p_timer->start(t_bus);
00213 loadBusData(*Ret,false);
00214 if (p_timer) p_timer->stop(t_new);
00215 if (p_timer) p_timer->stop(t_bus);
00216 if (p_timer) t_branch = p_timer->createCategory("Mapper: Load Branch Data");
00217 if (p_timer) p_timer->start(t_branch);
00218 loadBranchData(*Ret,false);
00219 if (p_timer) p_timer->stop(t_branch);
00220 if (p_timer) t_set = p_timer->createCategory("Mapper: Set Matrix");
00221 if (p_timer) p_timer->start(t_set);
00222 GA_Pgroup_sync(p_GAgrp);
00223 Ret->ready();
00224 if (p_timer) p_timer->stop(t_set);
00225 return Ret;
00226 }
00227
00228
00229
00230
00231
00232
00233 void mapToMatrix(gridpack::math::Matrix &matrix)
00234 {
00235 int t_set, t_bus, t_branch;
00236 GA_Pgroup_sync(p_GAgrp);
00237 if (p_timer) t_set = p_timer->createCategory("Mapper: Set Matrix");
00238 if (p_timer) p_timer->start(t_set);
00239 matrix.zero();
00240 if (p_timer) p_timer->stop(t_set);
00241 if (p_timer) t_bus = p_timer->createCategory("Mapper: Load Bus Data");
00242 if (p_timer) p_timer->start(t_bus);
00243 loadBusData(matrix,false);
00244 if (p_timer) p_timer->stop(t_bus);
00245 if (p_timer) t_branch = p_timer->createCategory("Mapper: Load Branch Data");
00246 if (p_timer) p_timer->start(t_branch);
00247 loadBranchData(matrix,false);
00248 if (p_timer) p_timer->stop(t_branch);
00249 if (p_timer) p_timer->start(t_set);
00250 GA_Pgroup_sync(p_GAgrp);
00251 matrix.ready();
00252 if (p_timer) p_timer->stop(t_set);
00253 }
00254
00255
00256
00257
00258
00259 void mapToRealMatrix(gridpack::math::RealMatrix &matrix)
00260 {
00261 int t_set, t_bus, t_branch;
00262 GA_Pgroup_sync(p_GAgrp);
00263 if (p_timer) t_set = p_timer->createCategory("Mapper: Set Matrix");
00264 if (p_timer) p_timer->start(t_set);
00265 matrix.zero();
00266 if (p_timer) p_timer->stop(t_set);
00267 if (p_timer) t_bus = p_timer->createCategory("Mapper: Load Bus Data");
00268 if (p_timer) p_timer->start(t_bus);
00269 loadRealBusData(matrix,false);
00270 if (p_timer) p_timer->stop(t_bus);
00271 if (p_timer) t_branch = p_timer->createCategory("Mapper: Load Branch Data");
00272 if (p_timer) p_timer->start(t_branch);
00273 loadRealBranchData(matrix,false);
00274 if (p_timer) p_timer->stop(t_branch);
00275 if (p_timer) p_timer->start(t_set);
00276 GA_Pgroup_sync(p_GAgrp);
00277 matrix.ready();
00278 if (p_timer) p_timer->stop(t_set);
00279 }
00280
00281
00282
00283
00284
00285 void mapToMatrix(boost::shared_ptr<gridpack::math::Matrix> &matrix)
00286 {
00287 mapToMatrix(*matrix);
00288 }
00289
00290
00291
00292
00293
00294 void mapToRealMatrix(boost::shared_ptr<gridpack::math::RealMatrix> &matrix)
00295 {
00296 mapToRealMatrix(*matrix);
00297 }
00298
00299
00300
00301
00302
00303
00304 void overwriteMatrix(gridpack::math::Matrix &matrix)
00305 {
00306 GA_Pgroup_sync(p_GAgrp);
00307 loadBusData(matrix,false);
00308 loadBranchData(matrix,false);
00309 GA_Pgroup_sync(p_GAgrp);
00310 matrix.ready();
00311 }
00312
00313
00314
00315
00316
00317
00318 void overwriteMatrix(boost::shared_ptr<gridpack::math::Matrix> &matrix)
00319 {
00320 overwriteMatrix(*matrix);
00321 }
00322
00323
00324
00325
00326
00327
00328 void incrementMatrix(gridpack::math::Matrix &matrix)
00329 {
00330 GA_Pgroup_sync(p_GAgrp);
00331 loadBusData(matrix,true);
00332 loadBranchData(matrix,true);
00333 GA_Pgroup_sync(p_GAgrp);
00334 matrix.ready();
00335 }
00336
00337
00338
00339
00340
00341
00342 void incrementMatrix(boost::shared_ptr<gridpack::math::Matrix> &matrix)
00343 {
00344 incrementMatrix(*matrix);
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354 bool check(void)
00355 {
00356 int i,idx,jdx,isize,jsize,icnt;
00357 int msize, nsize;
00358 gridpack::component::BaseBusComponent *bus1;
00359 gridpack::component::BaseBusComponent *bus2;
00360 bool ok;
00361 for (i=0; i<p_nBranches; i++) {
00362 bus1 = dynamic_cast<gridpack::component::BaseBusComponent*>
00363 (p_network->getBranch(i)->getBus1().get());
00364 bus2 = dynamic_cast<gridpack::component::BaseBusComponent*>
00365 (p_network->getBranch(i)->getBus2().get());
00366 isize = 0;
00367 jsize = 0;
00368 if (p_network->getBranch(i)->matrixForwardSize(&isize,&jsize)) {
00369 p_network->getBranch(i)->getMatVecIndices(&idx, &jdx);
00370 if (idx >= p_minRowIndex && idx <= p_maxRowIndex) {
00371 ok = true;
00372 msize = 0;
00373 nsize = 0;
00374 bus1->matrixDiagSize(&msize, &nsize);
00375 if (nsize != isize) ok = false;
00376 msize = 0;
00377 nsize = 0;
00378 bus2->matrixDiagSize(&msize, &nsize);
00379 if (msize != jsize) ok = false;
00380 if (!ok) {
00381 printf("Forward mismatch for branch between %d and %d\n",
00382 bus1->getOriginalIndex(), bus2->getOriginalIndex());
00383 }
00384 }
00385 }
00386 isize = 0;
00387 jsize = 0;
00388 if (p_network->getBranch(i)->matrixReverseSize(&isize,&jsize)) {
00389 p_network->getBranch(i)->getMatVecIndices(&idx, &jdx);
00390 if (jdx >= p_minRowIndex && jdx <= p_maxRowIndex) {
00391 ok = true;
00392 msize = 0;
00393 nsize = 0;
00394 bus1->matrixDiagSize(&msize, &nsize);
00395 if (msize != jsize) ok = false;
00396 msize = 0;
00397 nsize = 0;
00398 bus2->matrixDiagSize(&msize, &nsize);
00399 if (nsize != isize) ok = false;
00400 if (!ok) {
00401 printf("Reverse mismatch for branch between %d and %d\n",
00402 bus1->getOriginalIndex(), bus2->getOriginalIndex());
00403 }
00404 }
00405 }
00406 }
00407 return ok;
00408 }
00409
00410 private:
00411
00412
00413
00414
00415 int getActiveBuses(void)
00416 {
00417 int nActiveBuses = 0;
00418 for (int i = 0; i<p_nBuses; i++) {
00419 if (p_network->getActiveBus(i)) {
00420 nActiveBuses++;
00421 }
00422 }
00423 return nActiveBuses;
00424 }
00425
00426
00427
00428
00429
00430 void setupGlobalArrays(int nActiveBuses)
00431 {
00432 int one = 1;
00433
00434 p_totalBuses = nActiveBuses;
00435
00436 char cplus[2];
00437 strcpy(cplus,"+");
00438 GA_Pgroup_igop(p_GAgrp,&p_totalBuses,one,cplus);
00439
00440
00441
00442 createIndexGA(&gaMatBlksI, p_totalBuses);
00443 createIndexGA(&gaMatBlksJ, p_totalBuses);
00444 }
00445
00446
00447
00448
00449
00450 void createIndexGA(int * handle, int size)
00451 {
00452 int one = 1;
00453 *handle = GA_Create_handle();
00454 GA_Set_data(*handle, one, &size, C_INT);
00455 GA_Set_pgroup(*handle,p_GAgrp);
00456 if (!GA_Allocate(*handle)) {
00457 char buf[256];
00458 sprintf(buf,"FullMatrixMap::createIndexGA: Unable to allocate distributed array\n");
00459 printf("%s",buf);
00460 throw gridpack::Exception(buf);
00461 }
00462 GA_Zero(*handle);
00463 }
00464
00465
00466
00467
00468
00469 void setupIndexingArrays()
00470 {
00471 int * iSizeArray = NULL;
00472 int * jSizeArray = NULL;
00473 int ** iIndexArray = NULL;
00474 int ** jIndexArray = NULL;
00475 int icount = 0;
00476 int jcount = 0;
00477
00478
00479 allocateIndexArray(p_nBuses, &iSizeArray, &jSizeArray, &iIndexArray,
00480 &jIndexArray);
00481
00482 loadBusArrays(iSizeArray, jSizeArray, iIndexArray, jIndexArray,
00483 &icount, &jcount);
00484 scatterIndexingArrays(iSizeArray, jSizeArray, iIndexArray, jIndexArray,
00485 icount, jcount);
00486 deleteIndexArrays(p_nBuses, iSizeArray, jSizeArray, iIndexArray,
00487 jIndexArray);
00488 GA_Pgroup_sync(p_GAgrp);
00489
00490
00491 icount = 0;
00492 jcount = 0;
00493 allocateIndexArray(p_nBranches, &iSizeArray, &jSizeArray, &iIndexArray,
00494 &jIndexArray);
00495 loadForwardBranchArrays(iSizeArray, jSizeArray, iIndexArray, jIndexArray,
00496 &icount, &jcount);
00497 scatterIndexingArrays(iSizeArray, jSizeArray, iIndexArray, jIndexArray,
00498 icount, jcount);
00499
00500 icount = 0;
00501 jcount = 0;
00502 loadReverseBranchArrays(iSizeArray, jSizeArray, iIndexArray, jIndexArray,
00503 &icount, &jcount);
00504 scatterIndexingArrays(iSizeArray, jSizeArray, iIndexArray, jIndexArray,
00505 icount, jcount);
00506
00507 deleteIndexArrays(p_nBranches, iSizeArray, jSizeArray, iIndexArray,
00508 jIndexArray);
00509 GA_Pgroup_sync(p_GAgrp);
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 void allocateIndexArray(int n, int ** iSizeArray, int ** jSizeArray,
00521 int *** iIndexArray, int *** jIndexArray)
00522 {
00523 *iSizeArray = new int[n];
00524 *jSizeArray = new int[n];
00525 *iIndexArray = new int*[n];
00526 *jIndexArray = new int*[n];
00527
00528 for(int i = 0; i < n; i++) {
00529 (*iIndexArray)[i] = new int;
00530 (*jIndexArray)[i] = new int;
00531 }
00532 }
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 void loadBusArrays(int * iSizeArray, int * jSizeArray,
00545 int ** iIndexArray, int ** jIndexArray, int *icount, int *jcount)
00546 {
00547 int index = 0;
00548 int iSize = 0;
00549 int jSize = 0;
00550 bool status = true;
00551
00552 *icount = 0;
00553 *jcount = 0;
00554
00555 int i,j,maxcol,idx,jdx;
00556
00557 p_maxcol = 0;
00558 std::vector<boost::shared_ptr<gridpack::component::BaseComponent> > branches;
00559
00560 bool chk;
00561
00562 #ifdef NZ_PER_ROW
00563 std::vector<int> nz_per_row;
00564 #endif
00565 for (i = 0; i < p_nBuses; i++) {
00566
00567 status = p_network->getBus(i)->matrixDiagSize(&iSize, &jSize);
00568 int isave = iSize;
00569 if (status) {
00570 maxcol = 0;
00571 p_network->getBus(i)->getMatVecIndex(&index);
00572 if (iSize > 0) {
00573 iSizeArray[*icount] = iSize;
00574 *(iIndexArray[*icount]) = index;
00575 (*icount)++;
00576 }
00577 if (jSize > 0) {
00578 jSizeArray[*jcount] = jSize;
00579 *(jIndexArray[*jcount]) = index;
00580 (*jcount)++;
00581 }
00582 maxcol += jSize;
00583 branches.clear();
00584 p_network->getBus(i)->getNeighborBranches(branches);
00585 #ifdef NZ_PER_ROW
00586
00587 #endif
00588
00589
00590 for(j = 0; j<branches.size(); j++) {
00591 branches[j]->getMatVecIndices(&idx, &jdx);
00592 if (index == idx) {
00593 chk = branches[j]->matrixForwardSize(&iSize, &jSize);
00594 } else {
00595 chk = branches[j]->matrixReverseSize(&iSize, &jSize);
00596 }
00597 if (chk) maxcol += jSize;
00598 #ifdef NZ_PER_ROW
00599
00600 #endif
00601 }
00602 if (p_maxcol < maxcol) p_maxcol = maxcol;
00603 #ifdef NZ_PER_ROW
00604
00605
00606 for (j=0; j<isave; j++) {
00607 nz_per_row.push_back(maxcol);
00608 }
00609
00610 #endif
00611 }
00612 }
00613
00614 #ifdef NZ_PER_ROW
00615 int size = nz_per_row.size();
00616 p_nz_per_row = new int[size];
00617 for (int i = 0; i<size; i++) {
00618 p_nz_per_row[i] = nz_per_row[i];
00619 }
00620 #endif
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633 void loadForwardBranchArrays(int * iSizeArray, int * jSizeArray,
00634 int ** iIndexArray, int ** jIndexArray, int * icount,
00635 int * jcount)
00636 {
00637 int iIndex = 0;
00638 int jIndex = 0;
00639 int iSize = 0;
00640 int jSize = 0;
00641 bool status = true;
00642
00643 *icount = 0;
00644 *jcount = 0;
00645 for (int i = 0; i < p_nBranches; i++) {
00646 status = p_network->getBranch(i)->matrixForwardSize(&iSize, &jSize);
00647 if (status) {
00648 p_network->getBranch(i)->getMatVecIndices(&iIndex, &jIndex);
00649 if (iSize > 0) {
00650 iSizeArray[*icount] = iSize;
00651 *(iIndexArray[*icount]) = iIndex;
00652 (*icount)++;
00653 }
00654 if (jSize > 0) {
00655 jSizeArray[*jcount] = jSize;
00656 *(jIndexArray[*jcount]) = jIndex;
00657 (*jcount)++;
00658 }
00659 }
00660 }
00661 }
00662
00663 void loadReverseBranchArrays(int * iSizeArray, int * jSizeArray,
00664 int ** iIndexArray, int ** jIndexArray, int * icount,
00665 int * jcount)
00666 {
00667 int iIndex = 0;
00668 int jIndex = 0;
00669 int iSize = 0;
00670 int jSize = 0;
00671 bool status = true;
00672
00673 *icount = 0;
00674 *jcount = 0;
00675 for (int i = 0; i < p_nBranches; i++) {
00676 status = p_network->getBranch(i)->matrixReverseSize(&iSize, &jSize);
00677 if (status) {
00678 p_network->getBranch(i)->getMatVecIndices(&iIndex, &jIndex);
00679 if (iSize > 0) {
00680 iSizeArray[*icount] = iSize;
00681 *(iIndexArray[*icount]) = jIndex;
00682 (*icount)++;
00683 }
00684 if (jSize > 0) {
00685 jSizeArray[*jcount] = jSize;
00686 *(jIndexArray[*jcount]) = iIndex;
00687 (*jcount)++;
00688 }
00689 }
00690 }
00691 }
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702 void deleteIndexArrays(int n, int * iSizeArray, int * jSizeArray,
00703 int ** iIndexArray, int ** jIndexArray)
00704 {
00705 for(int i = 0; i < n; i++) {
00706 delete iIndexArray[i];
00707 delete jIndexArray[i];
00708 }
00709 delete [] iIndexArray;
00710 delete [] jIndexArray;
00711
00712 delete [] iSizeArray;
00713 delete [] jSizeArray;
00714 }
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725 void scatterIndexingArrays(int * iSizeArray, int * jSizeArray,
00726 int ** iIndexArray, int ** jIndexArray,
00727 int icount, int jcount)
00728 {
00729 if (icount > 0) NGA_Scatter(gaMatBlksI, iSizeArray, iIndexArray, icount);
00730 if (jcount > 0) NGA_Scatter(gaMatBlksJ, jSizeArray, jIndexArray, jcount);
00731 }
00732
00733
00734
00735
00736
00737 void setupOffsetArrays()
00738 {
00739 int *itmp = new int[p_nNodes];
00740 int *jtmp = new int[p_nNodes];
00741
00742 int i, idx;
00743 int one = 1;
00744
00745
00746
00747
00748
00749 p_minRowIndex = p_totalBuses;
00750 p_maxRowIndex = 0;
00751 for (i=0; i<p_nBuses; i++) {
00752 if (p_network->getActiveBus(i)) {
00753 p_network->getBus(i)->getMatVecIndex(&idx);
00754 if (idx > p_maxRowIndex) p_maxRowIndex = idx;
00755 if (idx < p_minRowIndex) p_minRowIndex = idx;
00756 }
00757 }
00758
00759
00760 int nRows = p_maxRowIndex-p_minRowIndex+1;
00761 int *iSizes = new int[nRows];
00762 int *jSizes = new int[nRows];
00763 GA_Pgroup_sync(p_GAgrp);
00764 NGA_Get(gaMatBlksI,&p_minRowIndex,&p_maxRowIndex,iSizes,&one);
00765 NGA_Get(gaMatBlksJ,&p_minRowIndex,&p_maxRowIndex,jSizes,&one);
00766
00767
00768
00769 int iSize = 0;
00770 int jSize = 0;
00771 p_maxIBlock = 0;
00772 p_maxJBlock = 0;
00773 for (i=0; i<nRows; i++) {
00774 if (p_maxIBlock < iSizes[i]) p_maxIBlock = iSizes[i];
00775 if (p_maxJBlock < jSizes[i]) p_maxJBlock = jSizes[i];
00776 if (iSizes[i] > 0) iSize += iSizes[i];
00777 if (jSizes[i] > 0) jSize += jSizes[i];
00778
00779
00780
00781 }
00782 p_rowBlockSize = iSize;
00783 p_colBlockSize = jSize;
00784 char cmax[4];
00785 strcpy(cmax,"max");
00786 GA_Pgroup_igop(p_GAgrp,&p_maxIBlock,one,cmax);
00787 GA_Pgroup_igop(p_GAgrp,&p_maxJBlock,one,cmax);
00788
00789 for (i = 0; i<p_nNodes; i++) {
00790 itmp[i] = 0;
00791 jtmp[i] = 0;
00792 }
00793 itmp[p_me] = iSize;
00794 jtmp[p_me] = jSize;
00795
00796
00797 char cplus[2];
00798 strcpy(cplus,"+");
00799 GA_Pgroup_igop(p_GAgrp,itmp, p_nNodes, cplus);
00800 GA_Pgroup_igop(p_GAgrp,jtmp, p_nNodes, cplus);
00801
00802 int offsetArrayISize = 0;
00803 int offsetArrayJSize = 0;
00804 for (i = 0; i < p_me; i++) {
00805 offsetArrayISize += itmp[i];
00806 offsetArrayJSize += jtmp[i];
00807 }
00808
00809
00810
00811 int *offset = new int[p_nNodes];
00812 for (i=0; i<p_nNodes; i++) {
00813 offset[i] = 0;
00814 }
00815 offset[p_me] = p_activeBuses;
00816
00817 GA_Pgroup_igop(p_GAgrp,offset,p_nNodes,cplus);
00818
00819 int *mapc = new int[p_nNodes];
00820 mapc[0]=0;
00821 for (i=1; i<p_nNodes; i++) {
00822 mapc[i] = mapc[i-1] + offset[i-1];
00823 }
00824
00825 delete [] offset;
00826 delete [] itmp;
00827 delete [] jtmp;
00828
00829
00830 gaOffsetI = GA_Create_handle();
00831 GA_Set_data(gaOffsetI, one, &p_totalBuses, C_INT);
00832 GA_Set_irreg_distr(gaOffsetI, mapc, &p_nNodes);
00833 GA_Set_pgroup(gaOffsetI,p_GAgrp);
00834 if (!GA_Allocate(gaOffsetI)) {
00835 char buf[256];
00836 sprintf(buf,"FullMatrixMap::setupOffsetArrays: Unable to allocate distributed array for row offsets\n");
00837 printf("%s",buf);
00838 throw gridpack::Exception(buf);
00839 }
00840 GA_Zero(gaOffsetI);
00841
00842 gaOffsetJ = GA_Create_handle();
00843 GA_Set_data(gaOffsetJ, one, &p_totalBuses, C_INT);
00844 GA_Set_irreg_distr(gaOffsetJ, mapc, &p_nNodes);
00845 GA_Set_pgroup(gaOffsetJ,p_GAgrp);
00846 if (!GA_Allocate(gaOffsetJ)) {
00847 char buf[256];
00848 sprintf(buf,"FullMatrixMap::setupOffsetArrays: Unable to allocate distributed array for column offsets\n");
00849 printf("%s",buf);
00850 throw gridpack::Exception(buf);
00851 }
00852 GA_Zero(gaOffsetJ);
00853
00854
00855 int *iOffsets = new int[nRows];
00856 int *jOffsets = new int[nRows];
00857 iOffsets[0] = offsetArrayISize;
00858 jOffsets[0] = offsetArrayJSize;
00859 for (i=1; i<nRows; i++) {
00860 iOffsets[i] = iOffsets[i-1] + iSizes[i-1];
00861 jOffsets[i] = jOffsets[i-1] + jSizes[i-1];
00862 }
00863
00864
00865 if (nRows > 0) {
00866 NGA_Put(gaOffsetI,&p_minRowIndex,&p_maxRowIndex,iOffsets,&one);
00867 NGA_Put(gaOffsetJ,&p_minRowIndex,&p_maxRowIndex,jOffsets,&one);
00868 }
00869
00870
00871 GA_Destroy(gaMatBlksI);
00872 GA_Destroy(gaMatBlksJ);
00873
00874 GA_Pgroup_sync(p_GAgrp);
00875 delete [] mapc;
00876 delete [] iSizes;
00877 delete [] jSizes;
00878 delete [] iOffsets;
00879 delete [] jOffsets;
00880 }
00881
00882
00883
00884
00885
00886 void setBusOffsets(void)
00887 {
00888 int i,idx,isize,jsize,icnt;
00889 int **indices = new int*[p_busContribution];
00890 int *data = new int[p_busContribution];
00891 int *ptr = data;
00892 icnt = 0;
00893 boost::shared_ptr<gridpack::component::BaseBusComponent> bus;
00894 for (i=0; i<p_nBuses; i++) {
00895 if (p_network->getActiveBus(i)) {
00896 bus = p_network->getBus(i);
00897 if (bus->matrixDiagSize(&isize,&jsize)) {
00898 indices[icnt] = ptr;
00899 bus->getMatVecIndex(&idx);
00900 *(indices[icnt]) = idx;
00901 ptr++;
00902 icnt++;
00903 }
00904 }
00905 }
00906 if (icnt != p_busContribution) {
00907 char buf[256];
00908 sprintf(buf,"FullMatrixMap::setBusOffsets: Contribution from buses doesn't match\n");
00909 printf("%s",buf);
00910 throw gridpack::Exception(buf);
00911 }
00912
00913
00914 if (p_busContribution > 0) {
00915 p_i_busOffsets = new int[p_busContribution];
00916 p_j_busOffsets = new int[p_busContribution];
00917 NGA_Gather(gaOffsetI,p_i_busOffsets,indices,p_busContribution);
00918 NGA_Gather(gaOffsetJ,p_j_busOffsets,indices,p_busContribution);
00919 }
00920 if (p_busContribution > 0) {
00921 delete [] indices;
00922 delete [] data;
00923 }
00924 }
00925
00926
00927
00928
00929
00930
00931 void loadBusData(gridpack::math::Matrix &matrix, bool flag)
00932 {
00933 int i,idx,jdx,isize,jsize,icnt;
00934 boost::shared_ptr<gridpack::component::BaseBusComponent> bus;
00935
00936 ComplexType *values = new ComplexType[p_maxIBlock*p_maxJBlock];
00937 int j,k;
00938 int jcnt = 0;
00939 for (i=0; i<p_nBuses; i++) {
00940 if (p_network->getActiveBus(i)) {
00941 bus = p_network->getBus(i);
00942 if (bus->matrixDiagSize(&isize,&jsize)) {
00943 #ifdef DBG_CHECK
00944 int ijsize = isize*jsize;
00945 for (k=0; k<ijsize; k++) values[k] = 0.0;
00946 #endif
00947 if (bus->matrixDiagValues(values)) {
00948 icnt = 0;
00949 for (k=0; k<jsize; k++) {
00950 jdx = p_j_busOffsets[jcnt] + k;
00951 for (j=0; j<isize; j++) {
00952 idx = p_i_busOffsets[jcnt] + j;
00953 if (flag) {
00954 matrix.addElement(idx, jdx, values[icnt]);
00955 } else {
00956 matrix.setElement(idx, jdx, values[icnt]);
00957 }
00958 icnt++;
00959 }
00960 }
00961 }
00962 jcnt++;
00963 }
00964 }
00965 }
00966
00967
00968 delete [] values;
00969 }
00970
00971
00972
00973
00974
00975
00976 void loadRealBusData(gridpack::math::RealMatrix &matrix, bool flag)
00977 {
00978 int i,idx,jdx,isize,jsize,icnt;
00979 boost::shared_ptr<gridpack::component::BaseBusComponent> bus;
00980
00981 RealType *values = new RealType[p_maxIBlock*p_maxJBlock];
00982 int j,k;
00983 int jcnt = 0;
00984 for (i=0; i<p_nBuses; i++) {
00985 if (p_network->getActiveBus(i)) {
00986 bus = p_network->getBus(i);
00987 if (bus->matrixDiagSize(&isize,&jsize)) {
00988 #ifdef DBG_CHECK
00989 int ijsize = isize*jsize;
00990 for (k=0; k<ijsize; k++) values[k] = 0.0;
00991 #endif
00992 if (bus->matrixDiagValues(values)) {
00993 icnt = 0;
00994 for (k=0; k<jsize; k++) {
00995 jdx = p_j_busOffsets[jcnt] + k;
00996 for (j=0; j<isize; j++) {
00997 idx = p_i_busOffsets[jcnt] + j;
00998 if (flag) {
00999 matrix.addElement(idx, jdx, values[icnt]);
01000 } else {
01001 matrix.setElement(idx, jdx, values[icnt]);
01002 }
01003 icnt++;
01004 }
01005 }
01006 }
01007 jcnt++;
01008 }
01009 }
01010 }
01011
01012
01013 delete [] values;
01014 }
01015
01016
01017
01018
01019
01020
01021 void loadBusData(boost::shared_ptr<gridpack::math::Matrix> &matrix, bool flag)
01022 {
01023 loadBusData(*matrix, flag);
01024 }
01025
01026
01027
01028
01029
01030
01031 void loadRealBusData(boost::shared_ptr<gridpack::math::RealMatrix> &matrix, bool flag)
01032 {
01033 loadRealBusData(*matrix, flag);
01034 }
01035
01036
01037
01038
01039
01040 void setBranchOffsets(void)
01041 {
01042 int i,idx,jdx,isize,jsize,icnt;
01043 int **i_indices = new int*[p_branchContribution];
01044 int **j_indices = new int*[p_branchContribution];
01045 int *i_data = new int[p_branchContribution];
01046 int *j_data = new int[p_branchContribution];
01047 int *i_ptr = i_data;
01048 int *j_ptr = j_data;
01049 icnt = 0;
01050 int t_idx(0);
01051 if (p_timer) t_idx = p_timer->createCategory("setBranchOffsets: Set Index Arrays");
01052 if (p_timer) p_timer->start(t_idx);
01053 boost::shared_ptr<gridpack::component::BaseBranchComponent> branch;
01054 for (i=0; i<p_nBranches; i++) {
01055 branch = p_network->getBranch(i);
01056 if (branch->matrixForwardSize(&isize,&jsize)) {
01057 branch->getMatVecIndices(&idx, &jdx);
01058 if (idx >= p_minRowIndex && idx <= p_maxRowIndex) {
01059 i_indices[icnt] = i_ptr;
01060 j_indices[icnt] = j_ptr;
01061 *(i_indices[icnt]) = idx;
01062 *(j_indices[icnt]) = jdx;
01063 i_ptr++;
01064 j_ptr++;
01065 icnt++;
01066 }
01067 }
01068 if (branch->matrixReverseSize(&isize,&jsize)) {
01069 branch->getMatVecIndices(&idx, &jdx);
01070 if (jdx >= p_minRowIndex && jdx <= p_maxRowIndex) {
01071 i_indices[icnt] = i_ptr;
01072 j_indices[icnt] = j_ptr;
01073 *(i_indices[icnt]) = jdx;
01074 *(j_indices[icnt]) = idx;
01075 i_ptr++;
01076 j_ptr++;
01077 icnt++;
01078 }
01079 }
01080 }
01081 if (icnt != p_branchContribution) {
01082 char buf[256];
01083 sprintf(buf,"p[%d] Mismatch in loadBranchData icnt: %d branchContribution: %d\n",
01084 p_me,icnt,p_branchContribution);
01085 printf("%s",buf);
01086 throw gridpack::Exception(buf);
01087 }
01088 if (p_timer) p_timer->stop(t_idx);
01089
01090
01091 int t_gat(0);
01092 if (p_timer) t_gat = p_timer->createCategory("setBranchOffsets: Gather Offsets");
01093 if (p_timer) p_timer->start(t_gat);
01094 p_i_branchOffsets = new int[p_branchContribution];
01095 p_j_branchOffsets = new int[p_branchContribution];
01096 if (p_branchContribution > 0) {
01097 NGA_Gather(gaOffsetI,p_i_branchOffsets,i_indices,p_branchContribution);
01098 NGA_Gather(gaOffsetJ,p_j_branchOffsets,j_indices,p_branchContribution);
01099 }
01100 if (p_timer) p_timer->stop(t_gat);
01101
01102
01103 delete [] i_indices;
01104 delete [] j_indices;
01105 delete [] i_data;
01106 delete [] j_data;
01107 }
01108
01109
01110
01111
01112
01113
01114 void loadBranchData(gridpack::math::Matrix &matrix, bool flag)
01115 {
01116 int i,idx,jdx,isize,jsize,icnt;
01117
01118 int t_add(0);
01119 if (p_timer) t_add = p_timer->createCategory("loadBranchData: Add Matrix Elements");
01120 if (p_timer) p_timer->start(t_add);
01121 boost::shared_ptr<gridpack::component::BaseBranchComponent> branch;
01122 ComplexType *values = new ComplexType[p_maxIBlock*p_maxJBlock];
01123 int j,k;
01124 int jcnt = 0;
01125 for (i=0; i<p_nBranches; i++) {
01126 branch = p_network->getBranch(i);
01127 if (branch->matrixForwardSize(&isize,&jsize)) {
01128 branch->getMatVecIndices(&idx, &jdx);
01129 if (idx >= p_minRowIndex && idx <= p_maxRowIndex) {
01130 #ifdef DBG_CHECK
01131 int ijsize = isize*jsize;
01132 for (k=0; k<ijsize; k++) values[k] = 0.0;
01133 #endif
01134 if (branch->matrixForwardValues(values)) {
01135 icnt = 0;
01136 for (k=0; k<jsize; k++) {
01137 jdx = p_j_branchOffsets[jcnt] + k;
01138 for (j=0; j<isize; j++) {
01139 idx = p_i_branchOffsets[jcnt] + j;
01140 if (flag) {
01141 matrix.addElement(idx, jdx, values[icnt]);
01142 } else {
01143 matrix.setElement(idx, jdx, values[icnt]);
01144 }
01145 icnt++;
01146 }
01147 }
01148 }
01149 jcnt++;
01150 }
01151 }
01152 if (branch->matrixReverseSize(&isize,&jsize)) {
01153 branch->getMatVecIndices(&idx, &jdx);
01154 if (jdx >= p_minRowIndex && jdx <= p_maxRowIndex) {
01155 #ifdef DBG_CHECK
01156 int ijsize = isize*jsize;
01157 for (k=0; k<ijsize; k++) values[k] = 0.0;
01158 #endif
01159 if (branch->matrixReverseValues(values)) {
01160 icnt = 0;
01161
01162
01163 for (k=0; k<jsize; k++) {
01164 idx = p_j_branchOffsets[jcnt] + k;
01165 for (j=0; j<isize; j++) {
01166 jdx = p_i_branchOffsets[jcnt] + j;
01167 if (flag) {
01168 matrix.addElement(jdx, idx, values[icnt]);
01169 } else {
01170 matrix.setElement(jdx, idx, values[icnt]);
01171 }
01172 icnt++;
01173 }
01174 }
01175 }
01176 jcnt++;
01177 }
01178 }
01179 }
01180 if (p_timer) p_timer->stop(t_add);
01181
01182
01183 delete [] values;
01184 }
01185
01186
01187
01188
01189
01190
01191 void loadRealBranchData(gridpack::math::RealMatrix &matrix, bool flag)
01192 {
01193 int i,idx,jdx,isize,jsize,icnt;
01194
01195 int t_add(0);
01196 if (p_timer) t_add = p_timer->createCategory("loadBranchData: Add Matrix Elements");
01197 if (p_timer) p_timer->start(t_add);
01198 boost::shared_ptr<gridpack::component::BaseBranchComponent> branch;
01199 RealType *values = new RealType[p_maxIBlock*p_maxJBlock];
01200 int j,k;
01201 int jcnt = 0;
01202 for (i=0; i<p_nBranches; i++) {
01203 branch = p_network->getBranch(i);
01204 if (branch->matrixForwardSize(&isize,&jsize)) {
01205 branch->getMatVecIndices(&idx, &jdx);
01206 if (idx >= p_minRowIndex && idx <= p_maxRowIndex) {
01207 #ifdef DBG_CHECK
01208 int ijsize = isize*jsize;
01209 for (k=0; k<ijsize; k++) values[k] = 0.0;
01210 #endif
01211 if (branch->matrixForwardValues(values)) {
01212 icnt = 0;
01213 for (k=0; k<jsize; k++) {
01214 jdx = p_j_branchOffsets[jcnt] + k;
01215 for (j=0; j<isize; j++) {
01216 idx = p_i_branchOffsets[jcnt] + j;
01217 if (flag) {
01218 matrix.addElement(idx, jdx, values[icnt]);
01219 } else {
01220 matrix.setElement(idx, jdx, values[icnt]);
01221 }
01222 icnt++;
01223 }
01224 }
01225 }
01226 jcnt++;
01227 }
01228 }
01229 if (branch->matrixReverseSize(&isize,&jsize)) {
01230 branch->getMatVecIndices(&idx, &jdx);
01231 if (jdx >= p_minRowIndex && jdx <= p_maxRowIndex) {
01232 #ifdef DBG_CHECK
01233 int ijsize = isize*jsize;
01234 for (k=0; k<ijsize; k++) values[k] = 0.0;
01235 #endif
01236 if (branch->matrixReverseValues(values)) {
01237 icnt = 0;
01238
01239
01240 for (k=0; k<jsize; k++) {
01241 idx = p_j_branchOffsets[jcnt] + k;
01242 for (j=0; j<isize; j++) {
01243 jdx = p_i_branchOffsets[jcnt] + j;
01244 if (flag) {
01245 matrix.addElement(jdx, idx, values[icnt]);
01246 } else {
01247 matrix.setElement(jdx, idx, values[icnt]);
01248 }
01249 icnt++;
01250 }
01251 }
01252 }
01253 jcnt++;
01254 }
01255 }
01256 }
01257 if (p_timer) p_timer->stop(t_add);
01258
01259
01260 delete [] values;
01261 }
01262
01263
01264
01265
01266
01267
01268 void loadBranchData(boost::shared_ptr<gridpack::math::Matrix> &matrix, bool flag)
01269 {
01270 loadBranchData(*matrix, flag);
01271 }
01272
01273
01274
01275
01276
01277
01278 void loadRealBranchData(boost::shared_ptr<gridpack::math::Matrix> &matrix, bool flag)
01279 {
01280 loadRealBranchData(*matrix, flag);
01281 }
01282
01283
01284
01285
01286 void contributions(void)
01287 {
01288 int i;
01289
01290 int isize, jsize;
01291 p_busContribution = 0;
01292 for (i=0; i<p_nBuses; i++) {
01293 if (p_network->getActiveBus(i)) {
01294 if (p_network->getBus(i)->matrixDiagSize(&isize, &jsize)) p_busContribution++;
01295 }
01296 }
01297
01298
01299 int idx, jdx;
01300 p_branchContribution = 0;
01301 for (i=0; i<p_nBranches; i++) {
01302 if (p_network->getBranch(i)->matrixForwardSize(&isize, &jsize)) {
01303 p_network->getBranch(i)->getMatVecIndices(&idx, &jdx);
01304 if (idx >= p_minRowIndex && idx <= p_maxRowIndex) {
01305 p_branchContribution++;
01306 }
01307 }
01308 if (p_network->getBranch(i)->matrixReverseSize(&isize, &jsize)) {
01309 p_network->getBranch(i)->getMatVecIndices(&idx, &jdx);
01310 if (jdx >= p_minRowIndex && jdx <= p_maxRowIndex) {
01311 p_branchContribution++;
01312 }
01313 }
01314 }
01315 }
01316
01317
01318 int p_me;
01319 int p_nNodes;
01320
01321
01322 boost::shared_ptr<_network> p_network;
01323 int p_nBuses;
01324 int p_nBranches;
01325 int p_totalBuses;
01326 int p_activeBuses;
01327
01328
01329 int p_minRowIndex;
01330 int p_maxRowIndex;
01331 int p_rowBlockSize;
01332 int p_colBlockSize;
01333 int p_busContribution;
01334 int p_branchContribution;
01335 int p_maxIBlock;
01336 int p_maxJBlock;
01337 int p_maxcol;
01338 #ifdef NZ_PER_ROW
01339 int* p_nz_per_row;
01340 #endif
01341
01342 int* p_i_busOffsets;
01343 int* p_j_busOffsets;
01344 int* p_i_branchOffsets;
01345 int* p_j_branchOffsets;
01346
01347
01348 int gaMatBlksI;
01349 int gaMatBlksJ;
01350 int gaOffsetI;
01351 int gaOffsetJ;
01352 int p_GAgrp;
01353
01354
01355 gridpack::utility::CoarseTimer *p_timer;
01356
01357 };
01358
01359 }
01360 }
01361
01362 #endif //FULLMATRIXMAP_HPP_